package com.bondex.charter.service;

import com.bondex.charter.dao.CharterMainMapper;
import com.bondex.charter.maindata.pojo.api.BaseComContainerTypeVO;
import com.bondex.charter.pojo.ContainerInfo;
import com.bondex.charter.pojo.DataCount;
import com.bondex.charter.pojo.DataCountDetail;
import com.bondex.charter.pojo.OrderInfo4List;
import com.bondex.charter.pojo.SearchParam;
import com.bondex.global.pojo.PageTableParamT;
import com.bondex.global.pojo.ResultT;
import com.bondex.global.spring.SpringContextHolder;
import com.bondex.global.utils.JacksonUtil;
import com.bondex.global.utils.Tools;
import com.fasterxml.jackson.core.type.TypeReference;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 列表页面使用的服务层
 * Created by JD on 2021/9/14.
 */
@Service
public class ListService extends BaseService {

	@Resource
	private CharterMainMapper charterMainMapper;

	private static DataCount DATA_COUNT = new DataCount();//统计数据，暂定缓存一分钟
	private static Map<String, BaseComContainerTypeVO> CONTAINER_MAP = new HashMap<>();//箱型对应的箱子信息，优化查询TEU的速度

	/**
	 * 获取列表信息
	 *
	 * @param param
	 * @return
	 */
	public ResultT<List<OrderInfo4List>> getList(PageTableParamT<SearchParam> param) {
		ResultT<List<OrderInfo4List>> oResult = new ResultT<>(false);
		try {
			if (param == null) param = new PageTableParamT<SearchParam>();
			initPageTableParam(param);

			//入参SearchParam的处理
			if (param.getSearchParam() != null) {
				param.getSearchParam().setVesselNo("");
				param.getSearchParam().setVoyage("");

				//船名航次
				if (StringUtils.isNotBlank(param.getSearchParam().getVessel())) {
					String sVessel = param.getSearchParam().getVessel();
					sVessel = Tools.replaceWhitespace2Space(sVessel);
					sVessel = sVessel.replaceAll(" ", "%");
					param.getSearchParam().setVessel(sVessel);
				}

			}

			int nTotal = charterMainMapper.selectListCount(param);
			List<OrderInfo4List> oList = nTotal > 0 ? charterMainMapper.selectList(param) : new ArrayList<>();

			oResult.setSuccess(true);
			oResult.setData(oList);
			oResult.setTotal(nTotal);

		} catch (Exception e) {
			oResult.setSuccess(false);
			oResult.setMessage(e.getMessage());
		}
		return oResult;
	}

	/**
	 * 获取状态值统计
	 *
	 * @param param
	 * @return
	 */
	public ResultT<Map<String, Object>> getStatusCount(PageTableParamT<SearchParam> param) {
		try {

		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 数据统计
	 */
	public ResultT<DataCount> countData(PageTableParamT<SearchParam> param, String sToken) {
		ResultT<DataCount> oResult = new ResultT<>(false);
		try {
			if (false && DATA_COUNT != null
					&& (System.currentTimeMillis() - DATA_COUNT.getLastCountTime()) < 1000 * 60) {
				oResult.setSuccess(true);
				oResult.setData(DATA_COUNT);
			} else {
				if (DATA_COUNT == null) DATA_COUNT = new DataCount();

				//放舱统计用数据
				List<OrderInfo4List> oBookingList = charterMainMapper.selectBookingReleaseAll();
				DataCountDetail oDetailOfBooking = countBookingList2Detail(oBookingList, sToken);

				//截单统计用数据
				List<OrderInfo4List> oSiList = charterMainMapper.selectSiConfirmedAll();
				DataCountDetail oDetailOfSi = countSiList2Detail(oSiList, sToken);

				DATA_COUNT.setLastCountTime(System.currentTimeMillis());
				DATA_COUNT.setDetailOfBooking(oDetailOfBooking);
				DATA_COUNT.setDetailOfSi(oDetailOfSi);

				oResult.setSuccess(true);
				oResult.setData(DATA_COUNT);
			}
		} catch (Exception e) {
			oResult.setSuccess(false);
			oResult.setMessage(e.getMessage());
		}
		return oResult;
	}

	/**
	 * 计算数据统计-订舱
	 *
	 * @param list 数据库中查出来的数据列表
	 * @return
	 * @throws Exception
	 */
	private DataCountDetail countBookingList2Detail(List<OrderInfo4List> list, String sToken) throws Exception {
		DataCountDetail oResult = new DataCountDetail();
		oResult.setOrderCount(0);
		oResult.setContainerInfos(new HashMap<>());
		oResult.setContainerTEU(new BigDecimal(0));
		oResult.setTotalWeight(new BigDecimal(0));

		oResult.setOrderCount(list.size());
		if (oResult.getOrderCount() <= 0) return oResult;

		for (OrderInfo4List o : list) {
			List<ContainerInfo> oContainers = JacksonUtil.readValue((String) o.getContainerInfo(), new TypeReference<List<ContainerInfo>>() {
			});

			boolean bUseSi = "1".equals(o.getHasSi());
			for (ContainerInfo c : oContainers) {
				String sContainerType = c.getContainerType();

				//Map中追加同箱型的步长
				Tools.plusStepMap(oResult.getContainerInfos(), sContainerType);

				//获取等价TEU
				BigDecimal nTEU = getContainerTEU(sContainerType, sToken);
				oResult.setContainerTEU(oResult.getContainerTEU().add(nTEU));

				//若使用了SI，则计算SI中各个箱子的重量
				if (bUseSi) {
					oResult.setTotalWeight(oResult.getTotalWeight().add(c.getWeight()));
				}
			}

			//若未使用SI，则计算Booking中的毛重
			if (!bUseSi) {
				oResult.setTotalWeight(oResult.getTotalWeight().add(o.getGrossWeight()));
			}
		}
		return oResult;
	}

	/**
	 * 计算数据统计-截单
	 *
	 * @param list 数据库中查出来的数据列表
	 * @return
	 * @throws Exception
	 */
	private DataCountDetail countSiList2Detail(List<OrderInfo4List> list, String sToken) throws Exception {
		DataCountDetail oResult = new DataCountDetail();
		oResult.setOrderCount(0);
		oResult.setContainerInfos(new HashMap<>());
		oResult.setContainerTEU(new BigDecimal(0));
		oResult.setTotalWeight(new BigDecimal(0));

		oResult.setOrderCount(list.size());
		if (oResult.getOrderCount() <= 0) return oResult;

		for (OrderInfo4List o : list) {
			List<ContainerInfo> oContainers = JacksonUtil.readValue((String) o.getContainerInfo(), new TypeReference<List<ContainerInfo>>() {
			});

			for (ContainerInfo c : oContainers) {
				String sContainerType = c.getContainerType();

				//Map中追加同箱型的步长
				Tools.plusStepMap(oResult.getContainerInfos(), sContainerType);

				//获取等价TEU
				BigDecimal nTEU = getContainerTEU(sContainerType, sToken);
				oResult.setContainerTEU(oResult.getContainerTEU().add(nTEU));

				//计算SI中各个箱子的重量
				oResult.setTotalWeight(oResult.getTotalWeight().add(c.getWeight()));
			}
		}
		return oResult;
	}

	/**
	 * 根据箱型获取对应的TEU
	 */
	private BigDecimal getContainerTEU(String sContainerType, String sToken) {

		BaseComContainerTypeVO oContainer = CONTAINER_MAP.get(sContainerType);
		if (oContainer != null) {
			return oContainer.getEqualityTEU();
		} else {

			MainDataCacheService oMainData = SpringContextHolder.getBean(MainDataCacheService.class);
			List<BaseComContainerTypeVO> oContainerList = oMainData.getBaseComContainerTypeDTOList(sToken);
			if (oContainerList != null && oContainerList.size() > 0) {
				for (BaseComContainerTypeVO o : oContainerList) {
					if (sContainerType.equals(o.getContainerTypeCode())) {
						BigDecimal nTEU = new BigDecimal(o.getEquality());
						o.setEqualityTEU(nTEU);
						CONTAINER_MAP.put(sContainerType, o);
						return nTEU;
					}
				}
			}
		}
		return new BigDecimal(1);
	}


}
